#ifndef ALIYUN_JSON_READER_H_
#define ALIYUN_JSON_READER_H_

#include <map>
#include "core/utils/string_helper.h"

namespace aliyun {

class JsonReader {
public:
  JsonReader();

  void Parse(const char* buffer, size_t buffer_length, const string& base_key, std::map<string, string>& map);

private:
  enum TokenType {
    kTokenTypeUndefined,
    kTokenTypeArrayEnd,
    kTokenTypeObjectEnd,
    kTokenTypeComma,
    kTokenTypeColon,
    kTokenTypeNull,
    kTokenTypeBool,
    kTokenTypeNumber,
    kTokenTypeString,
  };
  struct Token {
    Token() : type((TokenType)0),value("") {}
    Token(TokenType t, const string& v) : type(t),value(v) {}
    TokenType type;
    string value;
  };

private:
  Token ReadJson(const string& base_key, std::map<string, string>& map);

  void ProcessObject(const string& base_key, std::map<string, string>& map);
  void ProcessList(const string& base_key, std::map<string, string>& map);
  void ProcessArray(const string& base_key, std::map<string, string>& map);

  Token ProcessNumber();
  void AddDigits(void);

  Token ProcessString(void);

  void SkipWhiteSpace(void);

  int CurrentChar(int* length = NULL);
  int NextChar(void);
  int PrevChar(void);
  void AddChar(int ch);
  void AddChar(void);
  string TrimFromLast(const string& str, const string& strip_string);
private:
  int c_;
  const char* buffer_;
  size_t buffer_length_;
  size_t buffer_index_;
  Token token_;
  string string_buffer;
};

} // namespace aliyun {

#endif // #ifndef ALIYUN_JSON_READER_H_

// end of file
